<?php
namespace console\controllers;

use Yii;
use yii\console\Controller;
use yii\db\Query;
use ReflectionClass;

/**
 * Crawl controller
 */
class CrawlController extends Controller
{
    const TASK_STATUS = 'task_status';

    /**
     * Displays homepage.
     *
     * @return mixed
     */
    public function actionIndex()
    {
        if($this->isTaskRunning()) {
            return;
        }

        $this->setTaskStatus('1');

        $dataQuery = (new Query())->select('*')
            ->from('crawl_task')
            ->where("`status`='0'")
            ->orderBy('tid ASC')
            ->createCommand(Yii::$app->db)
            ->queryAll();

        if(!empty($dataQuery)) {
            foreach($dataQuery as $item) {
                $taskAction = $item['action'];
                $this->runTask($taskAction, $item);
            }
        }

        $this->setTaskStatus('0');
    }

    /**
     * @param $taskAction string
     * @param $args array|null
     */
    private function runTask($taskAction, $args)
    {
        try {
            $actionArray = explode('/', $taskAction);
            $klassName = ucfirst($actionArray['0']) . 'Task';
            $actionName = 'action' . ucfirst($actionArray['1']);

            $refClass = new ReflectionClass('console\\models\\crawl\\'.$klassName);
            $refInstance = $refClass->newInstance();
            $methodRunAction = $refClass->getmethod($actionName);
            $methodRunAction->invokeArgs($refInstance, [$args]);
        } catch(\Exception $e) {
            Yii::error("Crawl action exception:: {$e->getMessage()}");
        }
    }

    private function isTaskRunning()
    {
        $isRunning = false;
        try {
            $dataQuery = (new Query())->select('*')
                ->from('crawl_meta')
                ->where("`name`=:name AND `value`<>'0'", [
                    ":name" => CrawlController::TASK_STATUS,
                ])
                ->createCommand(Yii::$app->db)
                ->queryOne();
            if(!empty($dataQuery)) {
                $isRunning = true;
                $taskInterval = 30 * 60;
                $timenow = time();
                $lasttime = intval($dataQuery['dateline']);
                if(($lasttime > 0)
                        && ($timenow - $lasttime > $taskInterval)) {
                    $isRunning = false;
                }
            }
        } catch(\Exception $e) {
        }
        return $isRunning;
    }

    private function setTaskStatus($status)
    {
        try {
            $dbConn = Yii::$app->db;
            $dateline = time();
            $dataQuery = (new Query())->select('name')
                ->from('crawl_meta')
                ->where("`name`=:name", [
                    ":name" => CrawlController::TASK_STATUS,
                ])
                ->createCommand(Yii::$app->db)
                ->queryOne();
            if(empty($dataQuery)) {
                $dbConn->createCommand()
                    ->insert('crawl_meta', [
                        'name' => CrawlController::TASK_STATUS,
                        'value' => $status,
                        'dateline' => $dateline,
                    ])
                    ->execute();
            } else {
                $dbConn->createCommand()
                    ->update('crawl_meta', [
                        'value' => $status,
                        'dateline' => $dateline,
                    ],
                    "`name`=:name", [
                        ":name" => CrawlController::TASK_STATUS,
                    ])
                    ->execute();
            }
        } catch(\Exception $e) {
        }
    }

}